package com.zues.java_test.crud.method;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

/**
 * @ClassName CrudService
 * @Description TODO
 * @Author zeus
 * @Date 3/7/2025 4:18 下午
 * @Version 1.0
 **/
public class CrudService {

    public <T> void updateList(List<T> currentRecords, List<T> updateRecords, Predicate<T> matchPredicate) throws IllegalAccessException {
        // 创建一个映射来存储当前记录，以ID为键
        Map<Object, T> currentMap = new HashMap<>();
        for (T record : currentRecords) {
            // 获取对象的第一个字段作为ID，这里需要更通用的方式来获取ID
            Field idField = record.getClass().getDeclaredFields()[0];
            idField.setAccessible(true); // 设置字段可访问
            Object idValue = idField.get(record); // 获取ID字段的值
            currentMap.put(idValue, record); // 将记录存入映射
        }

        // 创建一个映射来存储更新记录，以ID为键
        Map<Object, T> updateMap = new HashMap<>();
        for (T record : updateRecords) {
            Field idField = record.getClass().getDeclaredFields()[0];
            idField.setAccessible(true);
            Object idValue = idField.get(record);
            updateMap.put(idValue, record);
        }

        // 删除当前映射中不存在于更新映射中的记录
        currentMap.keySet().removeIf(id -> !updateMap.containsKey(id));
        currentRecords.clear(); // 清空当前记录列表
        currentRecords.addAll(currentMap.values()); // 添加剩余的记录到列表

        // 遍历更新记录，执行更新或添加操作
        for (T updateRecord : updateRecords) {
            Field idField = updateRecord.getClass().getDeclaredFields()[0];
            idField.setAccessible(true);
            Object idValue = idField.get(updateRecord);

            T currentRecord = currentMap.get(idValue);
            if (currentRecord != null) {
                // 如果当前记录存在，则更新它
                updateObject(currentRecord, updateRecord);
            } else {
                // 如果当前记录不存在，则添加新记录
                currentRecords.add(updateRecord);
            }
        }
    }

    // 一个私有方法，用于将源对象中的非空字段值复制到目标对象中
    private <T> void updateObject(T target, T source) throws IllegalAccessException {
        Field[] fields = target.getClass().getDeclaredFields(); // 获取目标对象的所有字段
        for (Field field : fields) {
            field.setAccessible(true); // 设置字段可访问
            Object sourceValue = field.get(source); // 获取源对象字段的值
            if (sourceValue != null) {
                // 如果源对象的字段值不为空，则复制到目标对象
                field.set(target, sourceValue);
            }
        }
    }

}
